package com.haisen.controller;

import com.alibaba.fastjson.JSON;
import com.haisen.core.shiro.credentials.CustomToken;
import com.haisen.core.utils.BaseController;
import com.haisen.core.utils.SpringUtils;
import com.haisen.core.utils.WebUtil;
import com.haisen.dataobject.entity.User;
import com.haisen.dataobject.enums.LoginType;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author cjbi
 */
@Controller
@Slf4j
public class LoginController extends BaseController {

    @GetMapping("/login")
    public String login(){
        return "system/login";
    }

    @PostMapping("/login")
    public String showLoginForm(HttpServletRequest request, Model model,String username,String password,boolean rememberMe) {
         log.info("登录提交参数：{},{},{}",username,password,rememberMe);
        //subject 主体，realm是验证主体的数据源
        Subject subject = SecurityUtils.getSubject();
        //生成token
        //UsernamePasswordAndClientToken token = new UsernamePasswordAndClientToken(username,password);
        CustomToken token = new CustomToken(username,password,rememberMe, LoginType.PASSWORD);
        String error = null;
        try {
            log.info("------身份验证token，登录");
            //会自动委托给Security Manager，调用之前必须通过SecurityUtils. setSecurityManager()设置；
            //在配置文件bean中设置，Security Manager负责逻辑，它会委托给Authenticator进行身份验证；
            //authenticator将token传入realm
            subject.login(token);
            //查看是否验证成功
            if (subject.isAuthenticated()){
                log.info("认证成功，sessionId={}", WebUtil.getInstance().getSessionId());
                SavedRequest savedRequest = WebUtils.getSavedRequest(request);
                String url = savedRequest!=null?savedRequest.getRequestUrl():null;
//                if(url!=null)
//                    return "redirect:"+url;
                return "redirect:/";
            }
        } catch (UnknownAccountException e) {//未知用户异常
            error = "用户名/密码错误";
        } catch (LockedAccountException e) {//账户锁定
            error = "账户被锁定！";
        } catch (CredentialsException e) {//用户密码错误异常
            error = "用户凭证错误！";
        } catch (Exception e) {
            e.printStackTrace();
            error = "其他异常！";
        }
        if (!StringUtils.isEmpty(error)){
            model.addAttribute("error", error);
            token.clear();
            return "system/login";
        }
        log.info("认证失败，错误：{}",error);
        return "system/login";
       // return "/system/main";
    }

 /*   @RequestMapping("/login")
    public String showLoginForm(HttpServletRequest req, Model model) {
        String exceptionClassName = (String)req.getAttribute("shiroLoginFailure");
        // Enumeration<String> enums = req.getAttributeNames();
        //  log.info("res属性:{}", JSONObject.toJSONString(enums));
        logger.info("begin to login");
        String error = null;
        if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
            error = "用户名/密码错误";
        } else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
            error = "用户名/密码错误";
        } else if(ExcessiveAttemptsException.class.getName().equals(exceptionClassName)) {
            error = "登陆失败次数过多";
        } else if(exceptionClassName != null) {
            error = "其他错误：" + exceptionClassName;
        }
        model.addAttribute("error", error);
        //这里不处理shiro登录成功,由shiro来处理,成功后访问地址应该时拦截前的地址
        return "system/login";
    }*/


    @RequestMapping("/main")
    public String main() throws Exception {
        //logger.info("begin to main");
        return "/system/main";
    }
}
